﻿namespace LP
{
    using System;
    using System.Collections.Generic;

    public abstract class AbsModule : CancelTokenPattern, IFixedUpdate, IUpdate, ICanUpdate
    {
        public bool IsUpdate { get; set; } = true;

        private Dictionary<Type, AbsMgr> mgrs = new Dictionary<Type, AbsMgr>();

        public override void OnDestroy()
        {
            foreach (var item in mgrs.Values)
            {
                item.OnDestroy();
            }
            mgrs.Clear();
            base.OnDestroy();
        }

        public virtual void OnFixedUpdate(float delta)
        {
            foreach (var item in mgrs.Values)
            {
                item.OnFixedUpdate(delta);
            }
        }

        public override void OnInit()
        {
            base.OnInit();
            RegMgrs();
        }

        public virtual void OnUpdate(float delta)
        {
            foreach (var item in mgrs.Values)
            {
                if (item.IsUpdate)
                {
                    item.OnUpdate(delta);
                }
            }
        }

        public abstract void RegMgrs();

        public T RegMgr<T>() where T : AbsMgr
        {
            T mgr = default;
            Type type = typeof(T);
            if (!mgrs.ContainsKey(type))
            {
                mgr = Activator.CreateInstance(type, true) as T;
                mgrs.Add(type, mgr);
                mgr.OnInit();
            }
            return mgr;
        }

        public void UnRegMgr<T>() where T : AbsMgr
        {
            Type type = typeof(T);
            if (mgrs.TryGetValue(type, out AbsMgr mgr))
            {
                mgr.OnDestroy();
                mgrs.Remove(type);
            }
        }

        public T RetrieveMgr<T>() where T : AbsMgr
        {
            T ret = default;
            Type type = typeof(T);
            if (mgrs.TryGetValue(type, out AbsMgr mgr))
            {
                ret = mgr as T;
            }
            return ret;
        }

        public override void OnInitFinish()
        {
            base.OnInitFinish();
            foreach (var item in mgrs.Values)
            {
                item.OnInitFinish();
            }
        }
    }
}